/*
 *axios封装
 * 请求拦截、相应拦截、错误统一处理
 */
import axios from 'axios';
import { _tiper, LOAD } from '@/base/util/ui';
import { api } from '@/common/config/api';

axios.defaults.timeout = 120000; // 请求超时时间
// axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'; // post json 编码

/**
 * 请求拦截器
 * TODO 后续根据网关拦截实现
 */

axios.interceptors.request.use(
  config => {
    return config;
  },
  error => {
    return Promise.error(error);
  }
);
/**
 * 响应拦截器
 * TODO 定义错误发生的处理事件
 */

axios.interceptors.response.use(
  response => {
    if (response.status === 200) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  // 服务器状态码不是200的情况
  error => {
    if (error.response.status) {
      switch (error.response.status) {
        case 404:
          _tiper.error('接口请求不存在');
          break;
        // 其他错误，直接抛出错误提示
        case 500:
          _tiper.error('error', '请求系统数据异常');
          break;
        default:
          _tiper.error(
            '状态码：' +
              error.response.status +
              ' 接口请求过程异常：' +
              error.response.data.message
              ? '系统异常'
              : JSON.stringify(error.response.data.message)
          );
      }
      return Promise.reject(error.response);
    }
  }
);

/**
 * 从api配置中获取接口方法名称
 * @param {String} method 方法key
 * @param {Object} config 接口配置
 * @returns 
 */
function getMethodFromApi(method) {
  const config = { ...api }
  const methodArr = method.split('.');
  if (methodArr.length === 2) {
    const a = methodArr[0]
    const b = methodArr[1]
    if (config[a]) {
      if (config[a][b]) {
        return config[a][b]
      } else {
        return config[a]
      }
    }
  }
  return method;
}

/**
 * axios post 请求
 * @param {String} method [请求接口方法名称]
 * @param {Object} param [请求参数]
 * @param {Object} options [加载框参数]
 */

function postJson(method, param, options) {
  return new Promise((resolve, reject) => {
    // 根据jcf对接口请求封装
    const postParam = param;
    loading(true, options);
    axios
      .post(getMethodFromApi(method), postParam)
      .then(res => {
        resolve(res.data);
        loading(false, options);
      })
      .catch(err => {
        reject(err.data);
        loading(false, options);
      });
  });
}

function postForm(method, param, options) {
  return new Promise((resolve, reject) => {
    // 根据jcf对接口请求封装

    let formData = new FormData();
    Object.keys(param).forEach(key => {
      formData.append(key, param[key]);
    });
    const postParam = formData;
    loading(true, options);
    axios({
      url: getMethodFromApi(method),
      method: 'post',
      data: postParam,//格式传输变化
      contentType: 'application/x-www-form-urlencoded',//contentType请求头设置
    }).then(res => {
        resolve(res.data);
        loading(false, options);
      })
      .catch(err => {
        reject(err.data);
        loading(false, options);
      });
  });
}
/**
 * axios get 请求
 * @param {String} method [请求接口方法名称]
 * @param {Object} param [请求参数,如'/user?ID=12345' 应该为{ID: 12345}]
 */
function getJson(method, param, options) {
  return new Promise((resolve, reject) => {
    loading(true, options);
    axios
      .get(getMethodFromApi(method), {
        params: param
      })
      .then(res => {
        resolve(res.data);
        loading(false, options);
      })
      .catch(err => {
        reject(err.data);
        loading(false, options);
      });
  });
}
/**
 * 加载框事件
 * @param {boolean} flag  开关标志
 * @param {Object} options [加载框参数]
 */
function loading(flag, options) {
  options = options || {};
  const msg = options.msg ? options.msg : null;
  // let target = options.el ? options.el.replace(/#|\./,""): "";
  const target = options.el ? options.el : '';
  const loadingCount = request.temp['loadingCount' + target];
  const loadingInstance = request.temp['loadingInstance' + target];
  if (isNaN(loadingCount)) {
    request.temp['loadingCount' + target] = 0;
  }
  /* console.log(target);
  console.log(loadingCount);
  console.log(loadingInstance); */

  if (flag) {
    if (++request.temp['loadingCount' + target] === 1) {
      request.temp['loadingInstance' + target] = LOAD(msg, target);
    }
  } else {
    if (--request.temp['loadingCount' + target] === 0) {
      if (loadingInstance) {
        request.temp['loadingInstance' + target].close();
        request.temp['loadingInstance' + target] = null;
      }
    }
  }
}

/**
 * 附件下载方法
 * @param {*} param 
 * @param {*} method 
 * @param {*} fileName 
 * @param {*} options 
 * @returns 
 */
function postDownload(param, method, fileName, options) {
  let genfileName = fileName || '导出'
  return new Promise((resolve, reject) => {
    const postParam = param;
    loading(true, options);
    axios
      .post(getMethodFromApi(method), postParam, {
        emulateJSON: false,
        responseType: 'blob'
      })
      .then(res => {
        genfileName = genfileName + `.xlsx`
        const content = res.headers['content-disposition'];
        if (content) {
          const fileName2 = content.split('=')
          if (fileName2.length === 2) {
            genfileName = JSON.parse(fileName2[1])
          }
        }
        const link = document.createElement('a');
        const body = document.querySelector('body');
        const blob = new Blob([res.data], {
          type: 'application/octet-stream'
        });
        if (!!window.ActiveXObject || 'ActiveXObject' in window) {
          window.navigator.msSaveOrOpenBlob(blob, genfileName);
        } else {
          link.href = window.URL.createObjectURL(blob);
          link.download = genfileName;
          body.appendChild(link);
          link.click();
          body.removeChild(link);
          window.URL.revokeObjectURL(link.href);
        }
        loading(false, options);
      })
      .catch(err => {
        reject(err.data);
        loading(false, options);
      });
  });
}

const request = {
  postJson: postJson,
  getJson: getJson,
  postForm: postForm,
  postDownload: postDownload,
  temp: {
    loadingCount: 0, // 加载计数器
    loadingInstance: null // 加载实例
  }
};

export { request };
